// Copyright (c) XiGuan 2023
// Author： xiguan
// Email: xiguan.teng@qq.com
// Create on 2023/11/16
// TODO:
//

#ifndef WEBSERVER_HTTPREQUEST_H
#define WEBSERVER_HTTPREQUEST_H

#include <Buffer.h>
#include <Log.h>
#include <SqlConnPool.h>
#include <SqlConnRAII.h>

#include <string>
#include <unordered_map>
#include <unordered_set>

class HttpRequest {
 public:
  enum PARSE_STATE {
    REQUEST_LINE,
    HEADERS,
    BODY,
    FINISH,
  };

  enum HTTP_CODE {
    NO_REQUEST = 0,
    GET_REQUEST,
    BAD_REQUEST,
    NO_RESOURSE,
    FORBIDDENT_REQUEST,
    FILE_REQUEST,
    INTERNAL_ERROR,
    CLOSED_CONNECTION,
  };

 private:
  PARSE_STATE state_;    // 解析状态

  std::string method_;   // 请求方法
  std::string path_;     // 请求路径
  std::string version_;  // http 版本
  std::string body_;     // 请求体

  std::unordered_map<std::string, std::string> header_;
  std::unordered_map<std::string, std::string> post_;

  static const std::unordered_set<std::string> DEFAULT_HTML_;
  static const std::unordered_map<std::string, int> DEFAULT_HTML_TAG_;

 public:
  HttpRequest();
  ~HttpRequest() = default;

  void init();

  bool is_keep_alive() const;

  bool parse(Buffer &buffer);

  std::string &getMethod();
  std::string &getPath();
  std::string &path();
  std::string &getVersion();

 private:
  bool parse_request_line_(const std::string &line);
  bool parse_request_header_(const std::string &line);
  bool parse_request_body_(const std::string &line);

  void parse_path_();

  void parse_post();

  void parse_from_urlencoded_();

  static bool user_verify(const std::string &username,
                          const std::string &passwd, bool is_login);
  static int conver_hex(char ch);
};

#endif  // WEBSERVER_HTTPREQUEST_H
